home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Objects / funcobject.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-10  |  4.9 KB  |  229 lines

  1. /* Function object implementation */
  2.  
  3. #include "Python.h"
  4. #include "compile.h"
  5. #include "structmember.h"
  6. #include "protos/funcobject.h"
  7.  
  8. PyObject *
  9. PyFunction_New(code, globals)
  10.     PyObject *code;
  11.     PyObject *globals;
  12. {
  13.     PyFunctionObject *op = PyObject_NEW(PyFunctionObject,
  14.                         &PyFunction_Type);
  15.     if (op != NULL) {
  16.         PyObject *doc;
  17.         PyObject *consts;
  18.         Py_INCREF(code);
  19.         op->func_code = code;
  20.         Py_INCREF(globals);
  21.         op->func_globals = globals;
  22.         op->func_name = ((PyCodeObject *)code)->co_name;
  23.         Py_INCREF(op->func_name);
  24.         op->func_defaults = NULL; /* No default arguments */
  25.         consts = ((PyCodeObject *)code)->co_consts;
  26.         if (PyTuple_Size(consts) >= 1) {
  27.             doc = PyTuple_GetItem(consts, 0);
  28.             if (!PyString_Check(doc) && !PyUnicode_Check(doc))
  29.                 doc = Py_None;
  30.         }
  31.         else
  32.             doc = Py_None;
  33.         Py_INCREF(doc);
  34.         op->func_doc = doc;
  35.     }
  36.     return (PyObject *)op;
  37. }
  38.  
  39. PyObject *
  40. PyFunction_GetCode(op)
  41.     PyObject *op;
  42. {
  43.     if (!PyFunction_Check(op)) {
  44.         PyErr_BadInternalCall();
  45.         return NULL;
  46.     }
  47.     return ((PyFunctionObject *) op) -> func_code;
  48. }
  49.  
  50. PyObject *
  51. PyFunction_GetGlobals(op)
  52.     PyObject *op;
  53. {
  54.     if (!PyFunction_Check(op)) {
  55.         PyErr_BadInternalCall();
  56.         return NULL;
  57.     }
  58.     return ((PyFunctionObject *) op) -> func_globals;
  59. }
  60.  
  61. PyObject *
  62. PyFunction_GetDefaults(op)
  63.     PyObject *op;
  64. {
  65.     if (!PyFunction_Check(op)) {
  66.         PyErr_BadInternalCall();
  67.         return NULL;
  68.     }
  69.     return ((PyFunctionObject *) op) -> func_defaults;
  70. }
  71.  
  72. int
  73. PyFunction_SetDefaults(op, defaults)
  74.     PyObject *op;
  75.     PyObject *defaults;
  76. {
  77.     if (!PyFunction_Check(op)) {
  78.         PyErr_BadInternalCall();
  79.         return -1;
  80.     }
  81.     if (defaults == Py_None)
  82.         defaults = NULL;
  83.     else if (PyTuple_Check(defaults)) {
  84.         Py_XINCREF(defaults);
  85.     }
  86.     else {
  87.         PyErr_SetString(PyExc_SystemError, "non-tuple default args");
  88.         return -1;
  89.     }
  90.     Py_XDECREF(((PyFunctionObject *) op) -> func_defaults);
  91.     ((PyFunctionObject *) op) -> func_defaults = defaults;
  92.     return 0;
  93. }
  94.  
  95. /* Methods */
  96.  
  97. #define OFF(x) offsetof(PyFunctionObject, x)
  98.  
  99. static struct memberlist func_memberlist[] = {
  100.     {"func_code",    T_OBJECT,    OFF(func_code)},
  101.     {"func_globals",T_OBJECT,    OFF(func_globals),    READONLY},
  102.     {"func_name",    T_OBJECT,    OFF(func_name),        READONLY},
  103.     {"__name__",    T_OBJECT,    OFF(func_name),        READONLY},
  104.     {"func_defaults",T_OBJECT,    OFF(func_defaults)},
  105.     {"func_doc",    T_OBJECT,    OFF(func_doc)},
  106.     {"__doc__",    T_OBJECT,    OFF(func_doc)},
  107.     {NULL}    /* Sentinel */
  108. };
  109.  
  110. static PyObject *
  111. func_getattr(op, name)
  112.     PyFunctionObject *op;
  113.     char *name;
  114. {
  115.     if (name[0] != '_' && PyEval_GetRestricted()) {
  116.         PyErr_SetString(PyExc_RuntimeError,
  117.           "function attributes not accessible in restricted mode");
  118.         return NULL;
  119.     }
  120.     return PyMember_Get((char *)op, func_memberlist, name);
  121. }
  122.  
  123. static int
  124. func_setattr(op, name, value)
  125.     PyFunctionObject *op;
  126.     char *name;
  127.     PyObject *value;
  128. {
  129.     if (PyEval_GetRestricted()) {
  130.         PyErr_SetString(PyExc_RuntimeError,
  131.           "function attributes not settable in restricted mode");
  132.         return -1;
  133.     }
  134.     if (strcmp(name, "func_code") == 0) {
  135.         if (value == NULL || !PyCode_Check(value)) {
  136.             PyErr_SetString(
  137.                 PyExc_TypeError,
  138.                 "func_code must be set to a code object");
  139.             return -1;
  140.         }
  141.     }
  142.     else if (strcmp(name, "func_defaults") == 0) {
  143.         if (value != Py_None && !PyTuple_Check(value)) {
  144.             PyErr_SetString(
  145.                 PyExc_TypeError,
  146.                 "func_defaults must be set to a tuple object");
  147.             return -1;
  148.         }
  149.         if (value == Py_None)
  150.             value = NULL;
  151.     }
  152.     return PyMember_Set((char *)op, func_memberlist, name, value);
  153. }
  154.  
  155. static void
  156. func_dealloc(op)
  157.     PyFunctionObject *op;
  158. {
  159.     Py_DECREF(op->func_code);
  160.     Py_DECREF(op->func_globals);
  161.     Py_DECREF(op->func_name);
  162.     Py_XDECREF(op->func_defaults);
  163.     Py_XDECREF(op->func_doc);
  164.     PyObject_DEL(op);
  165. }
  166.  
  167. static PyObject*
  168. func_repr(op)
  169.     PyFunctionObject *op;
  170. {
  171.     char buf[140];
  172.     if (op->func_name == Py_None)
  173.         sprintf(buf, "<anonymous function at %lx>", (long)op);
  174.     else
  175.         sprintf(buf, "<function %.100s at %lx>",
  176.             PyString_AsString(op->func_name),
  177.             (long)op);
  178.     return PyString_FromString(buf);
  179. }
  180.  
  181. static int
  182. func_compare(f, g)
  183.     PyFunctionObject *f, *g;
  184. {
  185.     int c;
  186.     if (f->func_globals != g->func_globals)
  187.         return (f->func_globals < g->func_globals) ? -1 : 1;
  188.     if (f->func_defaults != g->func_defaults) {
  189.         if (f->func_defaults == NULL)
  190.             return -1;
  191.         if (g->func_defaults == NULL)
  192.             return 1;
  193.         c = PyObject_Compare(f->func_defaults, g->func_defaults);
  194.         if (c != 0)
  195.             return c;
  196.     }
  197.     return PyObject_Compare(f->func_code, g->func_code);
  198. }
  199.  
  200. static long
  201. func_hash(f)
  202.     PyFunctionObject *f;
  203. {
  204.     long h;
  205.     h = PyObject_Hash(f->func_code);
  206.     if (h == -1) return h;
  207.     h = h ^ (long)f->func_globals;
  208.     if (h == -1) h = -2;
  209.     return h;
  210. }
  211.  
  212. PyTypeObject PyFunction_Type = {
  213.     PyObject_HEAD_INIT(&PyType_Type)
  214.     0,
  215.     "function",
  216.     sizeof(PyFunctionObject),
  217.     0,
  218.     (destructor)func_dealloc, /*tp_dealloc*/
  219.     0,        /*tp_print*/
  220.     (getattrfunc)func_getattr, /*tp_getattr*/
  221.     (setattrfunc)func_setattr, /*tp_setattr*/
  222.     (cmpfunc)func_compare, /*tp_compare*/
  223.     (reprfunc)func_repr, /*tp_repr*/
  224.     0,        /*tp_as_number*/
  225.     0,        /*tp_as_sequence*/
  226.     0,        /*tp_as_mapping*/
  227.     (hashfunc)func_hash, /*tp_hash*/
  228. };
  229.